
#include "KDTree.h"
#include "KDTreeLearner.h" 

#include "MREAgent.h"

KDTreeLearner::KDTreeLearner(MREAgent* m, int an, int od, taskspec_t& spec)
:SimpleTFGeneralizer(m,an,od,spec), MatlabDrawer("tfGeneralize")
{
	setSubplotDimension(od, an); 

	KDTree*** klearners =  new KDTree** [an]; 

	for(int i=0; i< action_number; i++)
	{
		klearners[i] = new KDTree* [od]; 
		
		for(int j=0; j< od; j++)	//set the parameters of each learner(each output)
		{
/*			klearners[i][j].setSplitCriterion(KDTree::SPLIT_USE_MAX_SAMPLES ); 
			learners[i][j].maxNumberOfSamples = 30; 
*/
			klearners[i][j] = new KDTree(); 
			klearners[i][j]->dimension = od; 
			klearners[i][j]->ranges = spec.double_observations;  
			klearners[i][j]->knownMaxLength = 0.3;  //this is normalized
			klearners[i][j]->maxNumberOfSamples = 10; 
			klearners[i][j]->knownMinPoints = od+4; 
			klearners[i][j]->maxAllowedError = (spec.double_observations[j].max - spec.double_observations[j].min )/10; 
			klearners[i][j]->setDimensionParameters(spec.num_double_observations, spec.double_observations); 

//			klearners[i][j]->generalizerType = KDTree::GENERALIZER_USE_LINEAR ; 
//			klearners[i][j]->splitCriterion = KDTree::SPLIT_USE_MAX_ALLOWED_ERROR; 
			klearners[i][j]->generalizerType = KDTree::GENERALIZER_USE_MEAN ; 
			klearners[i][j]->splitCriterion = KDTree::SPLIT_USE_MAX_SAMPLES ; 
		}
	}

	learners = (Regressor***) klearners; 

}

KDTreeLearner::~KDTreeLearner()
{
	for(int i=0; i< action_number; i++)
	{
		for(int j=0; j< obs_dim; j++)	//set the parameters of each learner(each output)
		{
			delete learners[i][j]; 
		}
		delete[] learners[i]; 
	}
	delete[] learners; 
}


void KDTreeLearner::batchLearn( list<Transition>& history)
{
	/*
	printf("size of our list is: %d\n", dataPoints.size()); 
	for(list<Observation>::iterator it= dataPoints.begin(); it!= dataPoints.end(); it++)
		MREAgent::printObservation(*it); 

	exit(0); 
	*/

}

/*
recursively fill in the information of the kdtree. 
*/
void KDTreeLearner::drawGridsEX(KNode* node, MatlabMatrix<double>& storage, int& index)
{
	if (!node || !node->box)
		return;

	//right the information for this node
	storage(index,0) = node->box->mins[0]; 
	storage(index,1) = node->box->maxs[0]; 
	storage(index,2) = node->box->mins[1]; 
	storage(index,3) = node->box->maxs[1]; 
	storage(index,4) = node->getKnownness(); 

	index++; //increase the index

	//fill in the children
	if (node->left)
		drawGridsEX(node->left, storage, index); 
	
	if (node->right)
		drawGridsEX(node->right, storage, index); 
}

void KDTreeLearner::drawGrids()
{
	for(int i=0; i< obs_dim ; i++)
		for(int j=0; j< action_number; j++)
		{
			KNode * root = ((KDTree*) learners[j][i])->root; 
			if (! root)
				continue; 

			int rows = root->getNumberOfNodes(); 
			int cols = 5;	// box min and max for the two dimension and the value of the box

			// allocation
			MatlabMatrix<double> vals(rows, cols); 

			//fill in the information
			int tmp = 0; 
			drawGridsEX(root,vals, tmp); 

			//call the parent who knows actually how to draw things in matlab
			MatlabDrawer::drawGrids(vals, 1+ (i)*action_number + j); 
		}


}




